package com.jkoss.wine.shiro;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.Condition;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.jkoss.base.controller.BaseController;
import com.jkoss.common.util.CommonUtil;
import com.jkoss.common.util.Constant;
import com.jkoss.wine.system.entity.Loginlog;
import com.jkoss.wine.system.entity.MerchantEmployees;
import com.jkoss.wine.system.entity.Permission;
import com.jkoss.wine.system.entity.Role;
import com.jkoss.wine.system.service.ILoginlogService;
import com.jkoss.wine.system.service.IMerchantEmployeesRoleService;
import com.jkoss.wine.system.service.IMerchantEmployeesService;
import com.jkoss.wine.system.service.IPermissionService;

public class AuthRealm extends AuthorizingRealm {

	@Autowired
	private SessionDAO sessionDAO;
	@Autowired
	private IMerchantEmployeesService iMerchantEmployeesService;
	@Autowired
	private IPermissionService iPermissionService;
	@Autowired
	private IMerchantEmployeesRoleService iMerchantEmployeesRoleService;
	@Autowired
	private ILoginlogService iLoginlogService;

	// 认证.登录
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {

		UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
		// 根据名字查找
		Wrapper wrapper = Condition.create().eq("account_num", usernamePasswordToken.getUsername()).ne("del", 1);
		MerchantEmployees merchantEmployees = iMerchantEmployeesService.selectOne(wrapper);
		if (CommonUtil.isBlank(merchantEmployees)) {
			// 找不到用户
			throw new UnknownAccountException();
		}
		if (!CommonUtil.isEquals(merchantEmployees.getAccountPwd(), new String(usernamePasswordToken.getPassword()))) {
			// 密码错误
			throw new IncorrectCredentialsException();
		}
		if (CommonUtil.isEquals(merchantEmployees.getEmployeeState().toString(), "1")) {
			// 帐号停用
			throw new DisabledAccountException();
		}
		// 以下为只允许同一账户单个登录
		Collection<Session> sessions = sessionDAO.getActiveSessions();
		if (sessions.size() > 0) {
			for (Session session : sessions) {
				System.out.println("::::::::::::::::" + session);
				// 获得session中已经登录用户的名字
				if (null != session.getAttribute(Constant.SESSION_USER_KEY)) {
					if (CommonUtil.isEquals(((MerchantEmployees) session.getAttribute(Constant.SESSION_USER_KEY)).getEmployeeName(), merchantEmployees.getEmployeeName())) {
						sessionDAO.delete(session);
						// session.removeAttribute(Constant.SESSION_USER_KEY);
						System.out.println("清除了");
					}
				}
			}
		}

		// 查找所有权限
		List<Permission> permissions = iPermissionService.selectByMeid(merchantEmployees.getEmployeeId());

		List<Permission> menus = new ArrayList();
		List<String> urls = new ArrayList();

		if (!CommonUtil.isBlank(permissions)) {
			for (Permission permission : permissions) {
				if (CommonUtil.isBlank(permission.getPid())) {
					submenu(permission, permissions);
					menus.add(permission);
				}
				if (!CommonUtil.isBlank(permission.getUrl())) {
					urls.add(permission.getUrl());
				}
			}

			// for (TpPermission tpPermission : tpPermissions) {
			// if (CommonUtil.isEquals(tpPermission.getLevel(), 1)) {
			// menus.add(tpPermission);
			// }
			// if (CommonUtil.isEquals(tpPermission.getLevel(), 2)) {
			// menus.add(tpPermission);
			// urls.add(tpPermission.getUrl());
			// }
			// if (CommonUtil.isEquals(tpPermission.getLevel(), 3)) {
			// urls.add(tpPermission.getUrl());
			// }
			// }
		}

		// 查询当前用户的角色
		List<Role> roles = iMerchantEmployeesRoleService.selectMerchantEmployeesRole(merchantEmployees.getEmployeeId());
		SecurityUtils.getSubject().getSession(true).setAttribute(Constant.SESSION_USERROLE_KEY, roles);

		SecurityUtils.getSubject().getSession(true).setAttribute(Constant.SESSION_USER_KEY, merchantEmployees);
		// SecurityUtils.getSubject().getSession(true).setAttribute(Constant.SESSION_MENU_KEY,
		// menus);
		String menusJSON = JSON.toJSONString(menus);
		// System.out.println(menusJSON);
		SecurityUtils.getSubject().getSession(true).setAttribute(Constant.SESSION_MENU_KEY, menusJSON);
		SecurityUtils.getSubject().getSession(true).setAttribute(Constant.SESSION_URLS_KEY, urls);
		SecurityUtils.getSubject().getSession(true).setAttribute(Constant.SESSION_URLS_JSON, JSON.toJSONString(urls));
		return new SimpleAuthenticationInfo(merchantEmployees, merchantEmployees.getAccountPwd(), getName());
	}

	// 授权
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
		SimpleAuthorizationInfo simpleAuthenticationInfo = new SimpleAuthorizationInfo();
		simpleAuthenticationInfo.addStringPermissions((List) SecurityUtils.getSubject().getSession(true).getAttribute(Constant.SESSION_URLS_KEY));
		return simpleAuthenticationInfo;
	}

	private void submenu(Permission permission, List<Permission> permissions) {
		for (Permission permission2 : permissions) {
			if (CommonUtil.isEquals(permission.getId().toString(), permission2.getPid())) {
				List list = permission.getSubmenu();
				if (CommonUtil.isBlank(list)) {
					list = new ArrayList();
				}
				list.add(permission2);
				permission.setSubmenu(list);
				submenu(permission2, permissions);
			}
		}
	}

}